package com.yiren.dbaa.module.device.view.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.yiren.backstage.config.api.LoadConfigApi;
import com.yiren.backstage.config.bean.device.DeviceStudyConfigBean;
import com.yiren.backstage.currency.bean.GyroGearDataBean;
import com.yiren.backstage.currency.constant.SignalGConstant;
import com.yiren.backstage.currency.utils.StringUtil;
import com.yiren.dbaa.R;
import com.yiren.dbaa.activity.BaseActivity;
import com.yiren.dbaa.module.param_config.api.ParamConfigApi;
import com.yiren.dbaa.util.DensityUtil;
import com.yiren.dbaa.view.GyroGearPointView;
import com.yiren.dbaa.view.dialog.CustomDialog;
import com.yiren.dbaa.view.toast.MessageBox;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * @author lwb
 * @date :2022/1/19 15:16
 * @description: 新全档角度档位学习
 */
public class GYROStudyActivity extends BaseActivity {

    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_right)
    TextView tvRight;
    @BindView(R.id.tv_x)
    TextView tvX;
    @BindView(R.id.tv_y)
    TextView tvY;
    @BindView(R.id.tv_gears)
    TextView tvGears;
    @BindView(R.id.et_min_x1)
    EditText etMinX1;
    @BindView(R.id.et_max_x1)
    EditText etMaxX1;
    @BindView(R.id.et_min_y1)
    EditText etMinY1;
    @BindView(R.id.et_max_y1)
    EditText etMaxY1;
    @BindView(R.id.tv_study1)
    TextView tvStudy1;
    @BindView(R.id.et_min_x2)
    EditText etMinX2;
    @BindView(R.id.et_max_x2)
    EditText etMaxX2;
    @BindView(R.id.et_min_y2)
    EditText etMinY2;
    @BindView(R.id.et_max_y2)
    EditText etMaxY2;
    @BindView(R.id.tv_study2)
    TextView tvStudy2;
    @BindView(R.id.et_min_x3)
    EditText etMinX3;
    @BindView(R.id.et_max_x3)
    EditText etMaxX3;
    @BindView(R.id.et_min_y3)
    EditText etMinY3;
    @BindView(R.id.et_max_y3)
    EditText etMaxY3;
    @BindView(R.id.tv_study3)
    TextView tvStudy3;
    @BindView(R.id.et_min_x4)
    EditText etMinX4;
    @BindView(R.id.et_max_x4)
    EditText etMaxX4;
    @BindView(R.id.et_min_y4)
    EditText etMinY4;
    @BindView(R.id.et_max_y4)
    EditText etMaxY4;
    @BindView(R.id.tv_study4)
    TextView tvStudy4;
    @BindView(R.id.et_min_x5)
    EditText etMinX5;
    @BindView(R.id.et_max_x5)
    EditText etMaxX5;
    @BindView(R.id.et_min_y5)
    EditText etMinY5;
    @BindView(R.id.et_max_y5)
    EditText etMaxY5;
    @BindView(R.id.tv_study5)
    TextView tvStudy5;
    @BindView(R.id.et_min_x6)
    EditText etMinX6;
    @BindView(R.id.et_max_x6)
    EditText etMaxX6;
    @BindView(R.id.et_min_y6)
    EditText etMinY6;
    @BindView(R.id.et_max_y6)
    EditText etMaxY6;
    @BindView(R.id.tv_study6)
    TextView tvStudy6;
    @BindView(R.id.point_view)
    GyroGearPointView pointView;

    private TextView[] tvStudy;
    private EditText[] etMinX;
    private EditText[] etMaxX;
    private EditText[] etMinY;
    private EditText[] etMaxY;
    private StudyRunnable[] studyRun;

    private GyroGearDataBean data;
    private Handler gyroHandler;
    private Runnable gyroRunnable;
    private boolean isChange = false;  //数据是否改变

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gyro_study);
        ButterKnife.bind(this);
        initView();
        initData();
        gyroHandler = new Handler();
        refreshCarState();
    }

    /**
     * 刷新数据
     */
    private void refreshCarState() {
        gyroRunnable = new Runnable() {
            @Override
            public void run() {
                data.getGyroData(GYROStudyActivity.this);
                refresh();
                gyroHandler.postDelayed(gyroRunnable, 100);
            }
        };
        gyroHandler.post(gyroRunnable);// 启动定时器
    }

    private void initView() {
        tvTitle.setText("档位学习");
        tvRight.setVisibility(View.VISIBLE);
        tvRight.setText("使用说明");
        pointView.setMaxPoint1(20);
        tvStudy = new TextView[]{tvStudy1, tvStudy2, tvStudy3, tvStudy4, tvStudy5, tvStudy6};
        etMinX = new EditText[]{etMinX1, etMinX2, etMinX3, etMinX4, etMinX5, etMinX6};
        etMaxX = new EditText[]{etMaxX1, etMaxX2, etMaxX3, etMaxX4, etMaxX5, etMaxX6};
        etMinY = new EditText[]{etMinY1, etMinY2, etMinY3, etMinY4, etMinY5, etMinY6};
        etMaxY = new EditText[]{etMaxY1, etMaxY2, etMaxY3, etMaxY4, etMaxY5, etMaxY6};
        studyRun = new StudyRunnable[6];
    }

    private void initData() {
        data = new GyroGearDataBean(this);
        for (int i = 0; i < 6; i++) {
            studyRun[i] = new StudyRunnable(i + 1);
        }
        read();
    }

    @OnClick({R.id.iv_back, R.id.tv_right, R.id.tv_study1, R.id.tv_study2, R.id.tv_study3, R.id.tv_study4, R.id.tv_study5, R.id.tv_study6
            , R.id.tv_save, R.id.tv_read, R.id.tv_reset})
    public void onViewClicked(View v) {
        switch (v.getId()) {
            case R.id.iv_back:  //返回
                back();
                break;
            case R.id.tv_right: //使用说明
                showGyrosUseDialog();
                break;
            case R.id.tv_study1:
                study(1);
                break;
            case R.id.tv_study2:
                study(2);
                break;
            case R.id.tv_study3:
                study(3);
                break;
            case R.id.tv_study4:
                study(4);
                break;
            case R.id.tv_study5:
                study(5);
                break;
            case R.id.tv_study6:
                study(6);
                break;
            case R.id.tv_save:  //保存
                save();
                break;
            case R.id.tv_read:  //读取
                read();
                break;
            case R.id.tv_fix:   //修正
                fixMaxMin();
                break;
            case R.id.tv_reset: //重置差值
                if (data != null) {
                    data.reset();
                }
                break;
        }
    }

    private void showGyrosUseDialog() {
        AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.show();
        WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
        params.width = (int) ((DensityUtil.getScreenWidth(this) * 5) / 10);
        params.height = (DensityUtil.getScreenHeight(this) * 8) / 10;
        dialog.getWindow().setAttributes(params);
        Window window = dialog.getWindow();
        window.setContentView(R.layout.dialog_gyros_gears_use);
        ImageView ivCloseDialog = (ImageView) window.findViewById(R.id.iv_close_dialog);
        ivCloseDialog.setOnClickListener(v -> {
            dialog.dismiss();
        });
    }

    private void study(int index) {
        if (index <= 0 || index > 6) return;
        int studyIndex = getStudyRunningIndex();
        if (studyIndex == index) {
            studyRun[studyIndex - 1].isRunning = false;
        } else if (studyIndex > 0) {
            MessageBox.show(GYROStudyActivity.this, "正在学习其他档位，请先结束学习");
        } else {
            new Thread(studyRun[index - 1]).start();
        }
    }

    private int getStudyRunningIndex() {
        for (int i = 0; i < 6; i++) {
            if (studyRun[i].isRunning)
                return studyRun[i].index;
        }
        return 0;
    }

    /**
     * 保存
     */
    private void save() {
        for (int i = 0; i < 6; i++) {
            if (!studyRun[i].isReady()) {
                MessageBox.show(GYROStudyActivity.this, "尚未学习完成");
                return;
            }
        }
        if (data != null) {
            StringBuilder sb = new StringBuilder();
            sb.append(data.getOx()).append(",");
            sb.append(data.getOy()).append(",");
            sb.append(data.getOz()).append(",");
            for (int i = 0; i < 6; i++) {
                sb.append(studyRun[i].minX).append(",");
                sb.append(studyRun[i].maxX).append(",");
                sb.append(studyRun[i].minY).append(",");
                sb.append(studyRun[i].maxY);
                if (i != 5) {
                    sb.append(",");
                }
            }
            DeviceStudyConfigBean deviceStudyConfig = LoadConfigApi.loadDeviceStudyConfig(this);
            deviceStudyConfig.setGyroGearStudy(sb.toString());
            ParamConfigApi.saveDeviceStudyConfig(this, deviceStudyConfig);
            SignalGConstant.isAngleGearsChange = true;
            MessageBox.show(GYROStudyActivity.this, "保存成功");
            isChange = false;
        }
    }

    /**
     * 读取
     */
    private void read() {
        String str = LoadConfigApi.loadDeviceStudyConfig(this).getGyroGearStudy();
        if (str == null || str.length() == 0) return;
        System.out.println("hong +++++++++++++++ " + str);
        String[] list = str.split(",");
        if (list.length != 27) return;
        if (data != null) {
            data.reset(StringUtil.getStringFloat(list[0]), StringUtil.getStringFloat(list[1]), StringUtil.getStringFloat(list[2]));
            for (int i = 0; i < 6; i++) {
                studyRun[i].minX = StringUtil.getStringFloat(list[i * 4 + 3]);
                studyRun[i].maxX = StringUtil.getStringFloat(list[i * 4 + 4]);
                studyRun[i].minY = StringUtil.getStringFloat(list[i * 4 + 5]);
                studyRun[i].maxY = StringUtil.getStringFloat(list[i * 4 + 6]);
                tvStudy[i].setText("重新学习");
            }
            for (int i = 0; i < 6; i++) {
                studyRun[i].show();
            }
        }
    }

    /**
     * 修正
     */
    private void fixMaxMin() {
        for (int i = 0; i < 6; i++) {
            if (!studyRun[i].isReady()) {
                MessageBox.show(GYROStudyActivity.this, "尚未学习完成");
                return;
            }
        }
        if (isGearsR1()) {
            float x1 = studyRun[1].maxX;
            x1 = Math.max(x1, studyRun[3].maxX);
            float x2 = studyRun[1].minX;
            x2 = Math.min(x2, studyRun[3].minX);
            float x3 = studyRun[0].maxX;
            x3 = Math.min(x3, studyRun[2].maxX);
            x3 = Math.min(x3, studyRun[4].maxX);
            x3 = Math.min(x3, studyRun[5].maxX);
            float x4 = studyRun[0].minX;
            x4 = Math.min(x4, studyRun[2].minX);
            x4 = Math.min(x4, studyRun[4].minX);
            x4 = Math.min(x4, studyRun[5].minX);
            studyRun[1].maxX = studyRun[3].maxX = x1 + 10;
            studyRun[1].minX = studyRun[3].minX = x2 - (x2 - x3) / 5;
            studyRun[0].maxX = studyRun[2].maxX = studyRun[4].maxX = studyRun[5].maxX = x3 + (x2 - x3) / 5;
            studyRun[0].minX = studyRun[2].minX = studyRun[4].minX = studyRun[5].minX = x4 - 10;
            studyRun[5].minY = studyRun[5].minY - 10;
            studyRun[5].maxY = studyRun[0].minY = (studyRun[5].maxY + studyRun[0].minY) / 2;
            studyRun[0].maxY = studyRun[2].minY = (studyRun[0].maxY + studyRun[2].minY) / 2;
            studyRun[2].maxY = studyRun[4].minY = (studyRun[2].maxY + studyRun[4].minY) / 2;
            studyRun[4].maxY = studyRun[4].maxY + 10;
            studyRun[1].minY = studyRun[1].minY - 10;
            studyRun[1].maxY = studyRun[3].minY = (studyRun[1].maxY + studyRun[3].minY) / 2;
            studyRun[3].maxY = studyRun[3].maxY + 10;
        } else {
            float x1 = studyRun[1].maxX;
            x1 = Math.max(x1, studyRun[3].maxX);
            x1 = Math.max(x1, studyRun[5].maxX);
            float x2 = studyRun[1].minX;
            x2 = Math.min(x2, studyRun[3].minX);
            x2 = Math.min(x2, studyRun[5].minX);
            float x3 = studyRun[0].maxX;
            x3 = Math.min(x3, studyRun[2].maxX);
            x3 = Math.min(x3, studyRun[4].maxX);
            float x4 = studyRun[0].minX;
            x4 = Math.min(x4, studyRun[2].minX);
            x4 = Math.min(x4, studyRun[4].minX);
            studyRun[1].maxX = studyRun[3].maxX = studyRun[5].maxX = x1 + 10;
            studyRun[1].minX = studyRun[3].minX = studyRun[5].minX = x2 - (x2 - x3) / 5;
            studyRun[0].maxX = studyRun[2].maxX = studyRun[4].maxX = x3 + (x2 - x3) / 5;
            studyRun[0].minX = studyRun[2].minX = studyRun[4].minX = x4 - 10;
            float y1 = studyRun[0].minY;
            y1 = Math.min(y1, studyRun[1].minY);
            float y2 = (studyRun[0].maxY + studyRun[1].maxY + studyRun[2].minY + studyRun[3].minY) / 4;
            float y3 = (studyRun[2].maxY + studyRun[3].maxY + studyRun[4].minY + studyRun[5].minY) / 4;
            float y4 = studyRun[4].maxY;
            y4 = Math.max(y4, studyRun[5].maxY);
            studyRun[0].minY = studyRun[1].minY = y1 - 10;
            studyRun[0].maxY = studyRun[1].maxY = studyRun[2].minY = studyRun[3].minY = y2;
            studyRun[2].maxY = studyRun[3].maxY = studyRun[4].minY = studyRun[5].minY = y3;
            studyRun[4].maxY = studyRun[5].maxY = y4 + 10;
        }
        for (int i = 0; i < 6; i++) {
            studyRun[i].show();
        }
    }

    private boolean isGearsR1() {
        float x1 = (studyRun[0].maxX + studyRun[0].minX) / 2.0f;
        float x2 = (studyRun[1].maxX + studyRun[1].minX) / 2.0f;
        float x3 = (studyRun[2].maxX + studyRun[2].minX) / 2.0f;
        float x4 = (studyRun[3].maxX + studyRun[3].minX) / 2.0f;
        float x5 = (studyRun[4].maxX + studyRun[4].minX) / 2.0f;
        float x6 = (studyRun[5].maxX + studyRun[5].minX) / 2.0f;
        float cx = ((x1 + x3 + x5) / 3.0f + (x2 + x4) / 2.0f) / 2.0f;
        return x6 < cx;
    }

    private void refresh() {
        runOnUiThread(() -> {
            if (data != null) {
                float x = data.getDx();
                float y = data.getDy();
                addPoint(data.getDy(), -data.getDx());
                tvX.setText("X轴:" + ((int) (x * 100)) / 100.0f);
                tvY.setText("Y轴:" + ((int) (y * 100)) / 100.0f);
                tvGears.setText("档位:" + getGears(x, y));
            } else {
                data = new GyroGearDataBean(GYROStudyActivity.this);
            }
        });
    }

    private void addPoint(final float x, final float y) {
        runOnUiThread(() -> pointView.addPoint1(x, y));
    }

    private int getGears(float x, float y) {
        for (int i = 0; i < 6; i++) {
            if (studyRun[i].minX < x && x < studyRun[i].maxX && studyRun[i].minY < y && y < studyRun[i].maxY) {
                return i + 1;
            }
        }
        return 0;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            back();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void back() {
        if (isChange) {
            CustomDialog.Builder builder = new CustomDialog.Builder(this);
            builder.setMessage("您当前的学习数据尚未保存，是否立即保存？");
            builder.setTitle("温馨提示");
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    save();
                    dialog.dismiss();
                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    exit();
                }
            });
            builder.create().show();
        } else {
            exit();
        }
    }

    private void exit() {
        GYROStudyActivity.this.finish();
    }

    @Override
    protected void onDestroy() {
        for (int i = 0; i < 6; i++) {
            studyRun[i].isRunning = false;
        }
        if (gyroHandler != null && gyroRunnable != null) {
            gyroHandler.removeCallbacks(gyroRunnable);
        }
        super.onDestroy();
    }


    private class StudyRunnable implements Runnable {

        private boolean isRunning;
        private int index;
        private float minX, maxX;
        private float minY, maxY;

        StudyRunnable(int index) {
            this.isRunning = false;
            this.index = index;
            minX = maxX = minY = maxY = 0;
        }

        @Override
        public void run() {
            if (data != null) {
                isRunning = true;
                isChange = true;
                System.out.println("hong ++++++++++ StudyRunnable start: " + index);
                runOnUiThread(() -> tvStudy[index - 1].setText("结束"));
                minX = maxX = data.getDx();
                minY = maxY = data.getDy();
                while (isRunning) {
                    float x = data.getDx();
                    float y = data.getDy();
                    if (minX > x) minX = x;
                    if (maxX < x) maxX = x;
                    if (minY > y) minY = y;
                    if (maxY < y) maxY = y;
                    show();
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                runOnUiThread(() -> tvStudy[index - 1].setText("重新学习"));
                isRunning = false;
                System.out.println("hong ++++++++++ StudyRunnable finish: " + index);
            }
        }

        private void show() {
            minX = ((int) (minX * 100)) / 100.0f;
            maxX = ((int) (maxX * 100)) / 100.0f;
            minY = ((int) (minY * 100)) / 100.0f;
            maxY = ((int) (maxY * 100)) / 100.0f;
            pointView.setMaxMin(index - 1, maxY, minY, -minX, -maxX);
            runOnUiThread(() -> {
                etMinX[index - 1].setText("" + minX);
                etMaxX[index - 1].setText("" + maxX);
                etMinY[index - 1].setText("" + minY);
                etMaxY[index - 1].setText("" + maxY);
            });
        }

        private boolean isReady() {
            return !isRunning && minX != 0 && maxX != 0 && minY != 0 && maxY != 0;
        }
    }

}

